package by.bsu.scs.presentation.action;

import java.util.ArrayList;
import java.util.HashSet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

import by.bsu.scs.db.dao.MarkPolicyCriteriaHome;
import by.bsu.scs.db.dao.MarkPolicyHome;
import by.bsu.scs.model.MarkCriteria;
import by.bsu.scs.model.MarkPolicy;
import by.bsu.scs.model.MarkPolicyCriteria;
import by.bsu.scs.model.User;
import by.bsu.scs.presentation.form.MarkPolicyForm;
import by.bsu.scs.util.manager.SessionManager;

/**
 * @author Alexey Hursevich
 * @version 1.0
 * 
 * All actions connected with mark policies.
 */
public class MarkPolicyAction extends DispatchAction {
	
	public static final String MARK_POLICY_SAVED = "mp_saved";
	
	private static final String LIST = "list";
	private static final String CREATE = "create";
	private static final String EDIT = "edit";
	private static final String SAVE = "save";
	
	/**
	 * Lists mark policies created by the current instructor.
	 * <p>
	 * Retrieves user from session and finds appropriate
	 * mark policies in DB.
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return mapping forward path
	 */
	
	public ActionForward list(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		
		MarkPolicyForm mPForm = (MarkPolicyForm) form;
		MarkPolicyHome dao = new MarkPolicyHome();
		
		User instructor = SessionManager.getInstance().getUser(request);
		
		ArrayList<MarkPolicy> policiesOfInstructor = new ArrayList<MarkPolicy>( dao.getMarkPoliciesByIdCreator(instructor) );
		mPForm.setMarkPolicyList(policiesOfInstructor);
		
		return mapping.findForward(LIST);
	}
	
	/**
	 * Forwards to mark policy creation page.
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return mapping forward path
	 */
	public ActionForward create(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		return mapping.findForward(CREATE);
	}
	
	/**
	 * Gets policy id from request parameters and
	 * forward to editor page filling the field with 
	 * the current values of mark policy (selected for editing).
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return mapping forward path
	 */
	public ActionForward edit(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		
		MarkPolicyHome dao = new MarkPolicyHome();
		//Parameter 'policy_id' is generated in link for every mark policy instance
		MarkPolicy model = dao.findById( Integer.parseInt(request.getParameter("policy_id")) );
		
		MarkPolicyForm mPForm = (MarkPolicyForm) form;
		
		ArrayList<MarkPolicyCriteria> mPCriteriaList = new ArrayList<MarkPolicyCriteria>( model.getMarkPolicyCriteria() );
		
		mPForm.setPolicyId( model.getMarkPolicyId() );
		mPForm.setPolicyShort( model.getPolicyShort() );
		mPForm.setPolicyDescription( model.getPolicyDescription() );
		mPForm.setMarkPolicyCriteriaList(mPCriteriaList);
		
		return mapping.findForward(EDIT);
	}
	
	/**
	 * Saves created or edited mark policy and forwards to result page.
	 * <p>
	 * This methods is called when instructor saves just created mark policy
	 * or finishes the editing of already existed one.
	 * <p>
	 * All data is collected from submitted form, mark policy short name
	 * and description comes as one string, values are divided by '@'.
	 * <p>
	 * Operation type is defined by the hidden field 'operationType' of
	 * submitted form.
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return mapping forward path
	 */
	public ActionForward save(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		
		MarkPolicyForm mPForm = (MarkPolicyForm) form;
		
		String policyShort = mPForm.getPolicyShort();
		String policyDescription = mPForm.getPolicyDescription();
		
		MarkPolicy model = new MarkPolicy(policyShort);
		MarkPolicyHome dao = new MarkPolicyHome();
		
		HashSet<MarkPolicyCriteria> mPCriteria = new HashSet<MarkPolicyCriteria>();
		
		for( int i = 0; i < mPForm.getMarkPolicyCriteria().length; i ++ ) {
			String name = mPForm.getMarkPolicyCriteria()[i].split("@")[0];
			String discription = mPForm.getMarkPolicyCriteria()[i].split("@")[1];
			mPCriteria.add(new MarkPolicyCriteria(model, new MarkCriteria(name, discription)));
		}
		
		String operation = mPForm.getOperationType();
		
		if( operation.equalsIgnoreCase("create") ) {
			if( dao.findByExample(model).size() == 0 ) {
				model.setPolicyDescription(policyDescription);
				model.setMarkPolicyCriteria(mPCriteria);
				model.setIdCreator( SessionManager.getInstance().getUser(request).getUserId() );
				model.setVisible(true);
				dao.persist(model);
			} else {
				model.setPolicyDescription(policyDescription);
				model.setMarkPolicyCriteria(mPCriteria);
				model.setVisible(true);
				dao.merge(model);
			}
		}
		else if( operation.equalsIgnoreCase("edit") ) {
			MarkPolicy editModel = new MarkPolicyHome().findById( mPForm.getPolicyId() );
			editModel.setPolicyShort(policyShort);
			editModel.setPolicyDescription(policyDescription);
			dao.merge(editModel);	
			
			for(MarkPolicyCriteria mPC: mPCriteria) {
				mPC.setMarkPolicy(editModel);
				new MarkPolicyCriteriaHome().persist(mPC);
			}
		}
		
		request.setAttribute(MARK_POLICY_SAVED, policyShort);
		return mapping.findForward(SAVE);
	}
}
